package com.xy.sql.xml.kit;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 脚本工具类
 */
public class XySQLScriptKit {
    //\n
    public static char L_N = '\n';
    //\r
    public static char L_R = '\r';
    //\t
    public static char L_T = '\t';
    //单引号
    public static char SINGLE_QUOTE = '\'';
    //单引号
    public static String SINGLE_STR_QUOTE = String.valueOf(SINGLE_QUOTE);
    //双引号
    public static char DOUBLE_QUOTE = '"';
    //双引号
    public static String DOUBLE_STR_QUOTE = String.valueOf(DOUBLE_QUOTE);
    //开始字符
    public static char START_SIGN = '<';
    //结束字符
    public static char END_SIGN = '>';
    //开始字符
    public static String START_STR_SIGN = String.valueOf(START_SIGN);
    //结束字符
    public static String END_STR_SIGN = String.valueOf(END_SIGN);
    //<
    public static String LT = "&lt;";
    //>
    public static String GT = "&gt;";

    //正则表达式
    private static Pattern gtPattern = Pattern.compile(XySQLScriptKit.GT, Pattern.CASE_INSENSITIVE);
    private static Pattern ltPattern = Pattern.compile(XySQLScriptKit.LT, Pattern.CASE_INSENSITIVE);


    /**
     * SQL预处理
     *
     * @param condition
     * @return
     */
    public static String sqlPreProcess(String condition) {
        String newCond = condition;
        if (newCond.indexOf(GT) > 0) {
            newCond = replaceAll3(newCond, gtPattern, END_STR_SIGN);
        }
        if (newCond.indexOf(LT) > 0) {
            newCond = replaceAll3(newCond, ltPattern, START_STR_SIGN);
        }
        return newCond;
    }

    /***
     * replaceAll,忽略大小写
     *
     * @param input
     * @param p
     * @param replacement
     * @return
     */
    public static String replaceAll3(String input, Pattern p, String replacement) {
        Matcher m = p.matcher(input);
        return m.replaceAll(replacement);
    }


    /**
     * 参考org.springframework.jdbc.datasource.init.ScriptUtils#splitSqlScript
     *
     * @param script
     * @return
     */
    public static List<String> line(String script) throws Exception {
        return split(script, String.valueOf(L_N), "<!--", "-->");
    }

    /**
     * 分割属性列表
     *
     * @param tag
     * @param txt
     * @param splitChar
     * @return
     */
    public static Map<String, String> prop(String tag, String txt, String splitChar) throws Exception {
        Map<String, String> resMap = new HashMap<>();
        if (txt == null || txt.trim().length() <= tag.length()) {
            return resMap;
        }
        String sql = txt.trim().substring(tag.length());
        List<String> attList = split(sql, splitChar, null, null);
        String value;
        String key;
        int index;
        for (String att : attList) {
            index = att.indexOf("=");
            if (index > 0) {
                key = att.substring(0, index).trim();
                value = "";
                if (index < att.length() - 1) {
                    value = att.substring(index + 1).trim();
                    if (value.startsWith(DOUBLE_STR_QUOTE) || value.startsWith(SINGLE_STR_QUOTE)) {
                        if (value.length() > 2) {
                            value = value.substring(1, value.length() - 1);
                        }
                    }
                }
                resMap.put(key, value);
            } else {
                resMap.put(att, "");
            }
        }
        return resMap;
    }


    /**
     * 参考org.springframework.jdbc.datasource.init.ScriptUtils#splitSqlScript
     *
     * @param script
     * @param separator
     * @param blockCommentStartDelimiter
     * @param blockCommentEndDelimiter
     * @
     */
    private static List<String> split(String script, String separator, String blockCommentStartDelimiter, String blockCommentEndDelimiter) throws Exception {
        List<String> statements = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        boolean inDoubleQuote = false;
        boolean inSingleQuote = false;
        for (int i = 0; i < script.length(); ++i) {
            char c = script.charAt(i);
            if (!inDoubleQuote && c == SINGLE_QUOTE) {
                inSingleQuote = !inSingleQuote;
            } else if (!inSingleQuote && c == DOUBLE_QUOTE) {
                inDoubleQuote = !inDoubleQuote;
            }
            if (!inSingleQuote && !inDoubleQuote) {
                if (script.startsWith(separator, i)) {
                    if (sb.length() > 0) {
                        statements.add(sb.toString().trim());
                        sb = new StringBuilder();
                    }
                    i += separator.length() - 1;
                    continue;
                }
                if (blockCommentStartDelimiter != null && blockCommentStartDelimiter.length() > 0) {
                    int indexOfCommentEnd;
                    if (script.startsWith(blockCommentStartDelimiter, i)) {
                        indexOfCommentEnd = script.indexOf(blockCommentEndDelimiter, i);
                        if (indexOfCommentEnd <= i) {
                            throw new Exception("注解声明不全，确实开始或结束标志，标准格式<!-- -->");
                        }

                        i = indexOfCommentEnd + blockCommentEndDelimiter.length() - 1;
                        continue;
                    }
                }
            }
            //换行符 双引号中间的换行符，就直接跳过
            if (c != L_N && c != L_R) {
                if (c == L_T) {
                    c = ' ';
                }
                sb.append(c);
            }
        }

        if (sb.length() > 0) {
            statements.add(sb.toString().trim());
        }
        return statements;
    }


    /**
     * @param value
     * @param beginSign
     * @param endSign
     * @return
     */
    public static String trim(String value, String beginSign, String endSign) {
        if (value == null) {
            return "";
        }
        String temp = value.trim();
        String newValue = temp.toUpperCase();
        if (beginSign != null && temp.length() > beginSign.length()) {
            String newSign = beginSign.toUpperCase();
            if (newValue.startsWith(newSign)) {
                if (temp.length() == beginSign.length()) {
                    return "";
                }
                temp = temp.substring(beginSign.length());
            }
        }
        if (endSign != null && temp.length() >= endSign.length()) {
            String newSign = endSign.toUpperCase();
            if (newValue.endsWith(newSign)) {
                if (temp.length() == endSign.length()) {
                    return "";
                }
                temp = temp.substring(0, temp.length() - temp.length());
            }
        }
        return temp;

    }

}
